<template>
  <div>
    <el-upload ref="uploadRef" action="#" :on-exceed="handleExceed" v-model:file-list="fileList" :auto-upload="false" :limit="1" :on-change="handleFileChange">
      <template #trigger>
        <el-button type="primary" :icon="UploadFilled">
          <upload-filled />
          {{ btnText }}
        </el-button>
      </template>
      <template #file="{ file }">
        <span>{{ file.name }}</span>
        <span style="float: right">
        <el-link type="primary" @click="priviewExcel(file)">预览</el-link>
        <el-link type="danger" @click="delFile(file)" style="margin-left: 16px">删除</el-link>
      </span>
      </template>
    </el-upload>
    <VueOfficeExcel :src="previewUrl" style='width: 100vw;height: 100vh;' v-if='previewUrl'></VueOfficeExcel>
  </div>
</template>

<script lang="tsx" setup>
import * as XLSX from 'xlsx';
import { ref } from 'vue';
import { UploadFilled } from '@element-plus/icons-vue';
import { genFileId, UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus';
import VueOfficeExcel from '@vue-office/excel';
// import { addDialog } from '@/components/ReDialog/index';
import { UploadFile } from 'element-plus/es/components/upload/src/upload';
import { ExcelData } from '@/components/uploadExcel/types';

const props = defineProps({
  btnText: { type: String, default: '上传' },
  headerRowIndex: {
    type: Array,
    default() {
      return [];
    }
  }
});

const uploadRef = ref<UploadInstance>();
const fileList = ref<UploadUserFile[]>([]);
const excelData = defineModel<ExcelData[]>();
/**
 * @Event: 文件数量当超出限制时，执行的钩子函数
 * @Description: 覆盖前一个文件
 * @param files 文件列表
 */
const handleExceed: UploadProps['onExceed'] = files => {
  uploadRef.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  uploadRef.value!.handleStart(file);
};
/**
 * @Event: 文件发生变化时触发
 * @Description: 对刚上传的文件进行处理
 * @param file 状态变化的文件
 */
const handleFileChange: UploadProps['onChange'] = file => {
  if (isExcel(file)) {
    readerData(file).then(res => {
      excelData.value = res;
    });
  }
};

/**
 * @params: file
 * @Description: 读取文件，并返回处理后的数据
 */
function readerData(file: UploadFile): Promise<ExcelData[]> {
  const rawFile = file.raw;
  return new Promise(resolve => {
    const reader = new FileReader();
    reader.onload = e => {
      const data = e.target.result;
      const workbook = XLSX.read(data, { type: 'array', cellDates: true });
      const excelData = [];
      workbook.SheetNames.forEach((sheetName, index) => {
        debugger;
        const worksheet = workbook.Sheets[sheetName];
        const header = getHeaderRow(worksheet, index);
        const results = XLSX.utils.sheet_to_json(worksheet, { range: props.headerRowIndex[index] });
        excelData.push({ header, results });
      });
      resolve(excelData);
    };
    reader.readAsArrayBuffer(rawFile);
  });
}

/**
 * @Description: 获取excel表头
 * @param sheet excel sheet对象
 */
function getHeaderRow(sheet: Object, index: number): any[] {
  const headers = [];
  const range: XLSX.Range = XLSX.utils.decode_range(sheet['!ref']);
  let C;
  range.s.r = props.headerRowIndex[index] || range.s.r;
  const R = range.s.r;
  /* start in the first row */
  for (C = range.s.c; C <= range.e.c; ++C) {
    /* walk every column in the range */
    const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })];
    /* find the cell in the first row */
    let hdr = 'UNKNOWN ' + C; // <-- replace with your desired default
    if (cell && cell.t) hdr = XLSX.utils.format_cell(cell);
    headers.push(hdr);
  }
  return headers;
}

/**
 * @Description: 删除文件
 * @param file 文件对象
 */
function delFile(file: UploadFile) {
  uploadRef.value.handleRemove(file);
}
const previewUrl = ref()
/**
 * @Description: 预览Excel文件
 * @param file 文件对象
 */
function priviewExcel(file): void {
  const fileReader = new FileReader();
  fileReader.readAsArrayBuffer(file.raw);
  let key = 0;
  fileReader.onload = e => {
    previewUrl.value = e.target.result;
  };
}

function isExcel(file) {
  const rawFile = file.raw;
  return /\.(xlsx|xls|csv)$/.test(rawFile.name);
}
</script>

<style scoped>
.excel-upload-input {
  z-index: -9999;
  display: none;
}

.drop {
  position: relative;
  width: 600px;
  height: 160px;
  margin: 0 auto;
  font-size: 24px;
  line-height: 160px;
  color: #bbb;
  text-align: center;
  border: 2px dashed #bbb;
  border-radius: 5px;
}
</style>
